home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / boot / scsiDiskBoot / devScsiDevice.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-06-13  |  8.1 KB  |  276 lines

  1. /* 
  2.  * devScsiDevice.c --
  3.  *
  4.  *    Routines for attaching/releasing/sending commands to SCSI device 
  5.  *    attached to SCSI HBAs.
  6.  *
  7.  * Copyright 1989 Regents of the University of California
  8.  * Permission to use, copy, modify, and distribute this
  9.  * software and its documentation for any purpose and without
  10.  * fee is hereby granted, provided that the above copyright
  11.  * notice appear in all copies.  The University of California
  12.  * makes no representations about the suitability of this
  13.  * software for any purpose.  It is provided "as is" without
  14.  * express or implied warranty.
  15.  */
  16.  
  17. #ifdef notdef
  18. static char rcsid[] = "$Header: /sprite/src/kernel/dev/RCS/devScsiDevice.c,v 1.2 89/05/23 10:23:26 mendel Exp Locker: brent $ SPRITE (Berkeley)";
  19. #endif /* not lint */
  20.  
  21. #include "sprite.h"
  22. #include "scsiDevice.h"
  23. #include "scsiHBA.h"
  24. #include "dev/scsi.h"
  25. #include "scsi.h"
  26. #include "devQueue.h"
  27. #include "user/fs.h"
  28. #include "sync.h"    
  29. #include "stdlib.h"
  30.  
  31.  
  32.  
  33. /*
  34.  *----------------------------------------------------------------------
  35.  *
  36.  * DevScsiAttachDevice --
  37.  *
  38.  *    Return a handle that allows access to the specified SCSI device.
  39.  *
  40.  * Results:
  41.  *    A pointer to the ScsiDevice structure for the device. 
  42.  *    NIL if the device could not be attached.
  43.  *
  44.  * Side effects:
  45.  *    If the device is attached, an INQUIRY command is sent to the 
  46.  *    device.
  47.  *
  48.  *----------------------------------------------------------------------
  49.  */
  50.  
  51. ScsiDevice   *
  52. DevScsiAttachDevice(devicePtr, insertProc)
  53.     Fs_Device    *devicePtr;    /* Device to attach. */
  54.     void     (*insertProc)(); /* Insert procedure to use. */
  55. {
  56.     ScsiDevice   *handle;
  57.     ScsiCmd    inquiryCmdBlock;
  58.  
  59.     /*
  60.      * Call the Attach procedure for the HBA type specified in the Fs_Device.
  61.      */
  62.  
  63.     handle = (devScsiAttachProcs[0])(devicePtr,insertProc);
  64.     return handle;
  65. }
  66.  
  67. /*
  68.  * The following structure and routine are used to implement DevScsiSendCmdSync.
  69.  * The arguments to DevScsiSendCmdSync are stored in a SyncCmdBuf on 
  70.  * the caller's stack and DevScsiSendCmd is called. The call back function
  71.  * scsiDoneProc fills in the OUT arguments are wakes the caller.
  72.  *
  73.  */
  74. typedef struct SyncCmdBuf {
  75.     Sync_Semaphore mutex;      /* Lock for synronizing updates of 
  76.                    * this structure with the call back 
  77.                    * function. */
  78.     Sync_Condition wait;      /* Condition valued used to wait for
  79.                    * callback. */
  80.     Boolean      done;          /* Is the operation finished or not? */
  81.     unsigned char *statusBytePtr; /* Area to store SCSI status byte. */
  82.     int          *senseBufferLenPtr; /* Sense buffer length pointer. */
  83.     Address    senseBufferPtr;      /* Sense buffer. */
  84.     ReturnStatus status;         /* HBA error for command. */
  85.     int           *countPtr;      /* Btes transferred pointer. */
  86. } SyncCmdBuf;
  87.  
  88. /*
  89.  *----------------------------------------------------------------------
  90.  *
  91.  * scsiDoneProc --
  92.  *
  93.  *    This procedure is called when a scsi command started by 
  94.  *    DevScsiSendCmdSync finished. It's calling sequence is 
  95.  *    defined by the call back done by the DevScsiSendCmd routine.
  96.  *
  97.  * Results:
  98.  *    None
  99.  *
  100.  * Side effects:
  101.  *    A scsi command is executed.
  102.  *
  103.  *----------------------------------------------------------------------
  104.  */
  105.  
  106. static int
  107. scsiDoneProc(scsiCmdPtr, errorCode, statusByte, byteCount, 
  108.          senseDataLen, senseDataPtr)
  109.     ScsiCmd    *scsiCmdPtr;
  110.     ReturnStatus errorCode;
  111.     unsigned char statusByte;
  112.     int        byteCount;
  113.     int        senseDataLen;
  114.     Address    senseDataPtr;
  115. {
  116.     SyncCmdBuf    *syncCmdDataPtr = (SyncCmdBuf *) (scsiCmdPtr->clientData);
  117.     /*
  118.      * A pointer to a SyncCmdBuf is passed as the clientData to this call.
  119.      * Lock the structure, fill in the return values and wake up the
  120.      * initiator.
  121.      */
  122.     MASTER_LOCK(&syncCmdDataPtr->mutex);
  123.  
  124.     *(syncCmdDataPtr->statusBytePtr) = statusByte;
  125.     syncCmdDataPtr->status = errorCode;
  126.     *(syncCmdDataPtr->countPtr) = byteCount;
  127.     if (syncCmdDataPtr->senseBufferLenPtr != (int *) NIL) {
  128.     int    len;
  129.     len = *(syncCmdDataPtr->senseBufferLenPtr);
  130.     if (senseDataLen < len) {
  131.         len = senseDataLen;
  132.     }
  133.     bcopy(senseDataPtr, syncCmdDataPtr->senseBufferPtr, len);            *(syncCmdDataPtr->senseBufferLenPtr) = len;
  134.     }
  135.     syncCmdDataPtr->done = TRUE;
  136.     Sync_MasterBroadcast(&syncCmdDataPtr->wait);
  137.     MASTER_UNLOCK(&syncCmdDataPtr->mutex);
  138.     return (0);
  139.  
  140. }
  141.  
  142. /*
  143.  *----------------------------------------------------------------------
  144.  *
  145.  * DevScsiSendCmdSync --
  146.  *
  147.  *    Send a SCSI command block to the device specified in the 
  148.  *    ScsiDevice. This is the synchronous version that waits
  149.  *    for the status byte and sense data before returning.
  150.  *
  151.  * Results:
  152.  *    A ReturnStatus
  153.  *
  154.  * Side effects: 
  155.  *    A SCSI command block is sent to the device.  
  156.  *
  157.  *----------------------------------------------------------------------
  158.  *
  159.  */
  160. ReturnStatus
  161. DevScsiSendCmdSync(scsiDevicePtr, scsiCmdPtr, statusBytePtr, 
  162.             amountTransferredPtr,  senseBufferLenPtr, senseBufferPtr)
  163.     ScsiDevice *scsiDevicePtr;  /* Handle for target device. */
  164.     ScsiCmd    *scsiCmdPtr;            /* SCSI command to be sent. */
  165.     unsigned char *statusBytePtr; /* Area to store SCSI status byte. */
  166.     Address     senseBufferPtr;      /* Buffer to put sense data upon error. */
  167.     int        *senseBufferLenPtr; /*  IN - Length of senseBuffer available.
  168.                      * OUT - Length of senseData returned. */
  169.     int        *amountTransferredPtr; /* OUT - Nuber of bytes transferred. */
  170. {
  171.     ReturnStatus status;
  172.     SyncCmdBuf     syncCmdData;
  173.  
  174.     scsiCmdPtr->clientData = (ClientData) &syncCmdData;
  175.     scsiCmdPtr->doneProc = scsiDoneProc;
  176.     Sync_SemInitDynamic((&syncCmdData.mutex),"ScsiSyncCmdMutex");
  177.     syncCmdData.done = FALSE;
  178.     syncCmdData.statusBytePtr = statusBytePtr;
  179.     syncCmdData.senseBufferPtr = senseBufferPtr;
  180.     syncCmdData.senseBufferLenPtr = senseBufferLenPtr;
  181.     syncCmdData.countPtr = amountTransferredPtr;
  182.     boot_SendSCSICommand(scsiDevicePtr, scsiCmdPtr);
  183.     MASTER_LOCK((&syncCmdData.mutex));
  184.     while (syncCmdData.done == FALSE) { 
  185.     Sync_MasterWait((&syncCmdData.wait),(&syncCmdData.mutex),FALSE);
  186.     }
  187.     MASTER_UNLOCK((&syncCmdData.mutex));
  188.     status = syncCmdData.status;
  189.     return status;
  190. }
  191.  
  192.  
  193.  
  194. /*
  195.  *----------------------------------------------------------------------
  196.  *
  197.  * DevScsiSendCmd --
  198.  *
  199.  *    Send a SCSI command block to the device specified in the 
  200.  *    ScsiDevice.
  201.  *
  202.  * Results:
  203.  *    Nothing
  204.  *
  205.  * Side effects: 
  206.  *    A SCSI command block enqueue for the device.  The doneProc procedure
  207.  *    is call upon SCSI command completion.
  208.  *
  209.  *----------------------------------------------------------------------
  210.  *
  211.  * Due to the simplity of this routine and as an attempt to reduce procedure
  212.  * calling depth, this routine is coded as a macro and can be found in
  213.  * scsiHBAInt.h. 
  214.  */
  215. #ifndef DevScsiSendCmd
  216. void 
  217. DevScsiSendCmd(scsiDevicePtr, scsiCmdPtr)
  218.     ScsiDevice       *scsiDevicePtr;      /* Handle for target device. */
  219.     ScsiCmd         *scsiCmdPtr;        /* Command to be executed. */
  220. {
  221.      Dev_QueueInsert(scsiDevicePtr->devQueue, (List_Links *) scsiCmdPtr);
  222. }
  223. #endif /* DevScsiSendCmd */
  224.  
  225.  
  226. /*
  227.  *----------------------------------------------------------------------
  228.  *
  229.  * DevScsiReleaseDevice --
  230.  *
  231.  *     Release a device previously attached with ScsiAttachDevice().
  232.  *
  233.  * Results:
  234.  *    A ReturnStatus.
  235.  *
  236.  * Side effects: 
  237.  *    Unknown.
  238.  *
  239.  *----------------------------------------------------------------------
  240.  */
  241. ReturnStatus 
  242. DevScsiReleaseDevice(scsiDevicePtr)
  243.     ScsiDevice *scsiDevicePtr;  /* Handle for device to be released. */
  244. {
  245. }
  246.  
  247.  
  248. /*
  249.  *----------------------------------------------------------------------
  250.  *
  251.  *  DevScsiGetSenseCmd --
  252.  *
  253.  *     Procedure for formatting REQUEST SENSE.
  254.  *
  255.  * Results:
  256.  *    void
  257.  *
  258.  * Side effects: 
  259.  *    Unknown.
  260.  *
  261.  *----------------------------------------------------------------------
  262.  */
  263. void
  264. DevScsiSenseCmd(scsiDevicePtr, bufferSize, buffer, scsiCmdPtr)
  265.     ScsiDevice *scsiDevicePtr;  /* Handle for device to be released. */
  266.     int        bufferSize;    /* Size of request sense data buffer. */
  267.     char    *buffer;    /* Data buffer to put sense data. */
  268.     ScsiCmd    *scsiCmdPtr;    /* Scsi command buffer to fill in. */
  269. {
  270.     DevScsiGroup0Cmd(scsiDevicePtr, SCSI_REQUEST_SENSE, 0, 
  271.             (unsigned) bufferSize, scsiCmdPtr);
  272.     scsiCmdPtr->dataToDevice = FALSE;
  273.     scsiCmdPtr->bufferLen = bufferSize;
  274.     scsiCmdPtr->buffer = buffer;
  275. }
  276.